<template>
        <el-form label-width="120px" class="demo-ruleForm" :model="spuInfo" :rules="rules" ref="ruleFormRef" >
            <el-form-item label="SPU名称" prop='spuName'>
            <el-input  v-model="spuInfo.spuName" />
            </el-form-item>
            <el-form-item label="品牌" prop="tmId">
                <el-select  placeholder="请选择品牌" v-model="spuInfo.tmId">
                    <el-option v-for="trademark in trademarkList" :label="trademark.tmName" 
                    :key="trademark.id" :value="trademark.id" />
                </el-select>
            </el-form-item>
            <el-form-item label="Spu描述" prop="description">
                <el-input type="textarea" :rows="4"></el-input>
            </el-form-item>

            <!-- 图片 -->
            <el-form-item label="SPU图片" prop="spuImageList">
                <el-upload :action="`${BASE_URL}/admin/product/upload`" 
                list-type="picture-card" v-model:file-list="fileList"
                :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
                :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
                    <el-icon><Plus /></el-icon>
                </el-upload>
                <el-dialog v-model="dialogVisible">
                    <img w-full :src="dialogImageUrl" alt="Preview Image" />
                </el-dialog>
            </el-form-item>

            <!-- 销售属性 -->
            <el-form-item label="销售属性" prop="spuSaleAttrList">
                <el-select :placeholder="`还剩下${filterSaleAttrValue.length}个未选择`" v-model="spuInfo.spuSaleAttr">
                    <el-option v-for="baseSaleAttr in filterSaleAttrValue" :label='baseSaleAttr.name' 
                    :key='baseSaleAttr.id' :value="baseSaleAttr.name"/>
                </el-select>
                <el-button type="primary" :disabled="!spuInfo.spuSaleAttr" @click="addBaseSaleAttr">添加销售属性</el-button>
            </el-form-item>

            <!-- 表格 -->
            <el-form-item>
                <el-table border :data="spuInfo.spuSaleAttrList" style="margin-top:10px">
                    <el-table-column type="index" align="center" label="序号" width="80px" />
                    <el-table-column label="属性名" align="center" prop="saleAttrName" width="200px" />
                    <el-table-column label="属性值列表" align="center" >
                        <template v-slot="{row}">
                            <el-tag class="ml-2" style="margin-right:6px" type="success" v-for="tag in row.spuSaleAttrValueList" 
                            :key="tag" closable :disable-transitions="false" @close="handleClose(tag,row)">
                                {{tag.saleAttrValueName}}
                            </el-tag>
                            <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20" size="small" @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)" />
                            <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)">
                                + New
                            </el-button>
                        </template>
                    </el-table-column>
                    <el-table-column label="操作" width="200px">
                        <template v-slot="{row,$index}">
                            <el-button title="修改" size="small" type="warning" :icon="Edit" @click="editAttr(row,$index)"></el-button>
                            <el-popconfirm title="确定要删除此条属性吗?" @confirm="deleteAttrInfo($index)">
                                <template #reference>
                                <el-button title="删除" :icon="Delete" type="danger" size="small"></el-button>
                                </template>
                            </el-popconfirm> 
                        </template>
                    </el-table-column>
                </el-table>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="toAddOrUpdateAttr">保存</el-button>
                <el-button type="default" @click="emits('changeCompon',1)">取消</el-button>
            </el-form-item>
        </el-form>
</template>

<script lang="ts">
export default {
    name:"ApuForm"
}
</script>

<script lang="ts" setup>
import { ref,onMounted,reactive,computed,nextTick,defineEmits} from 'vue'
import { Delete,Plus} from '@element-plus/icons-vue'
import { ElMessage, type UploadProps, type UploadUserFile,ElInput} from 'element-plus'
import {reqGetAllTrademarkData,reqGetBaseSaleAttrData,reqAddSpuData} from '@/api/product/spu'
import type { FormInstance, FormRules } from 'element-plus'

const formSize = ref('default')
const ruleFormRef = ref<FormInstance>()

const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const BASE_URL = import.meta.env.VITE_API_URL
// 准备 品牌 和 销售属性 两个数组 保存数据 
const trademarkList = ref([])
const baseSaleAttrList = ref([])
const inputVisible = ref(false)
const inputValue = ref('')
const InputRef = ref<InstanceType<typeof ElInput>>()

const emits = defineEmits(['changeCompon'])
// 这是渲染页面的数据源 当给服务器的数据源添加数据时 fileList 会自动保存一份并给一个uuid 
// 可以解决 添加图片时的页面闪动问题 此外 还可以使用第三个参数 uploadFiles 解决闪动
const fileList = ref<UploadUserFile>([

])

// 1.定义一个存储spu相关数据的变量 这是发给服务器的数据源
const spuInfo = reactive({
  spuName: '',
  tmId: '', // spu品牌
  description: '', // spu描述
  spuImageList: [], // 存储spu图片的数组
  spuSaleAttrList: [], // 基本销售属性
  spuSaleAttr:'', // 收集选中的属性名
  category3Id:'' // 三级id
})

// 2.当组件挂载完成 立马同时发送请求拿到品牌数据 和 销售属性数据
onMounted(async()=>{
    try {
        const [responseTrademarkList,responseBaseSaleAttrList] = await Promise.all([reqGetAllTrademarkData(),reqGetBaseSaleAttrData()])
        trademarkList.value = responseTrademarkList
        baseSaleAttrList.value = responseBaseSaleAttrList
    } catch (error) {
        ElMessage.error('获取失败')
    }
})

// 3.图片上传前的格式校验
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (rawFile.type !== 'image/jpeg') {
    ElMessage.error('Avatar picture must be JPG format!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('Avatar picture size can not exceed 2MB!')
    return false
  }
  return true
}
// 4.图片上传成功(收集上传的图片名称和地址)
const handleAvatarSuccess: UploadProps['onSuccess'] = (response:any,uploadFile:any) => {
    spuInfo.spuImageList.push({
        imgName:uploadFile.name,
        imgUrl:response.data 
    })
    // 图片上传成功 清空校验
    ruleFormRef.value!.clearValidate(['spuImageList'])
}

// 5.缩略图上传之预览
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

// 6.删除图片成功后的操作(把剩余的图片数据重新赋值给spuInfo)
// uploadFile 被删除的图片 uploadFiles 剩余的图片数据
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  spuInfo.spuImageList = uploadFiles
}

// 7.添加销售属性值
// 1). 添加具体的详细属性值的时候，发现，如果有多行属性(比如至少有两行)，单击某一行的添加属性值按钮时，会影响到其它行，
// 究其原因，是因为控制按钮的属性是共用的，都是inputVisible，最好是以当前行的对象为准
// 2). 所以在添加销售属性的时候，就需要再添加一个属性inputVisible
const addBaseSaleAttr = ()=>{
    // 如果上一个属性的销售属性值为空 就不能添加新的属性名
    const flag = spuInfo.spuSaleAttrList.length&&spuInfo.spuSaleAttrList.some(item=>item.spuSaleAttrValueList.length===0)
    if(flag){
        ElMessage.error('添加失败')
        return
    }
    spuInfo.spuSaleAttrList.push({
        inputVisible:false,
        saleAttrName:spuInfo.spuSaleAttr, // 属性名
        spuSaleAttrValueList:[] // 属性值
    })
    // 清空下拉框选项
    spuInfo.spuSaleAttr=''

    // 清空校验
    ruleFormRef.value!.clearValidate(['spuImageList'])
}

// 8.获取剩余的销售属性名
// 从原始数据中遍历查找 要发给服务器的数据源中的数据
const filterSaleAttrValue = computed(()=>{
    return baseSaleAttrList.value.filter(item=>{
        return !spuInfo.spuSaleAttrList.find(spuSale=>item.name===spuSale.saleAttrName)
    })
})

// 9. 删除属性
const deleteAttrInfo = (index:number)=>{
 spuInfo.spuSaleAttrList.splice(index,1)
}

// 10.移除
const handleClose = (tag: string,row:any) => {
    row.spuSaleAttrValueList.splice( row.spuSaleAttrValueList.indexOf(tag), 1)
}

// 11.点击tag标签 出现输入框 并自动获取焦点
const showInput = (row) => {
  row.inputVisible= true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}

// 12.添加属性值
const handleInputConfirm = (row) => {
// 如果是重复项 则不添加 
  if (inputValue.value) {
    const res = row.spuSaleAttrValueList.some(item=>item.saleAttrValueName===inputValue.value)
    if(res){
        ElMessage.error('重复添加')
        // 关闭显示input框
        row.inputVisible = false
        // 清空input框
        inputValue.value = ''
        return
    }
    row.spuSaleAttrValueList.push({
      saleAttrValueName:inputValue.value,
      saleAttrName:row.saleAttrName
    })
  }
  row.inputVisible = false
  inputValue.value = ''
}

const rules = reactive<FormRules>({
    spuName: [
    { required: true, message: '请输入spu名称', trigger: 'blur' },
    { min: 3, max: 5, message: '长度应该在3到5个字间', trigger: 'blur' },
  ],
    tmId: [
    {
        required: true,
        message: '请选择spu品牌',
        trigger: 'change',
    },
  ],
    spuImageList: [
    {
        type: 'array',
        required: true,
        message: '请选择图片',
        trigger: 'change',
    },
  ],
    spuSaleAttrList: [
    {
        type: 'array',
        required: true,
        message: '请选择属性',
        trigger: 'change',
    },
  ],
    description: [
    { required: true, message: '请添加对spu的描述', trigger: 'blur' },
  ],
})

// 13.增加或更新spu
const toAddOrUpdateAttr = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate(async(valid, fields) => {
    if (valid) {
        // 判断有无属性值，如果有一项无值 不能提交
        const flag = spuInfo.spuSaleAttrList.length&&spuInfo.spuSaleAttrList.some(item=>item.spuSaleAttrValueList.length===0)
        if(flag) return ElMessage.error('提交失败，有属性值为空')
        await reqAddSpuData(spuInfo)
        emits('changeCompon',1)
    } else {
      console.log('error submit!', fields)
    }
  })
}

</script>

<style>

</style>